package com.dede.net_speed_monitor.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.net.TrafficStats;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.support.v4.content.LocalBroadcastManager;
import android.text.format.Formatter;
import android.util.Log;

import com.dede.net_speed_monitor.R;
import com.dede.net_speed_monitor.activity.SettingActivity;
import com.dede.net_speed_monitor.config.Config;
import com.dede.net_speed_monitor.util.NetTextIconFactory;
import com.dede.net_speed_monitor.util.NetUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.NumberFormat;

public class NetMonitorService extends Service {
    private static final String TAG = "NetMonitorService";

    private UpDateTask mTask;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mTask = new UpDateTask(this);
        new Thread(mTask).start();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mTask == null)
            return;
        mTask.stop();
        mTask = null;
    }

    public void reCreateNotify() {
        if (mTask == null) {
            mTask = new UpDateTask(this);
            new Thread(mTask).start();
            return;
        }
        mTask.reCreate();
    }

    public void cleanNotify() {
        if (mTask != null) {
            mTask.clean();
        }
    }

    public static class TileChangeListenerReceiver extends BroadcastReceiver {

        public static final String TITLE_CHANGE_ACTION = "TileChangeListener";

        private UpDateTask mTask;

        public TileChangeListenerReceiver(UpDateTask task) {
            mTask = task;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null && TITLE_CHANGE_ACTION.equals(intent.getAction())) {
                boolean state = intent.getBooleanExtra("state", false);
                Log.i(TAG, "onReceive: " + state);
                if (state) {//tile显示，移除通知
                    mTask.clean();
                } else {//tile隐藏，添加通知
                    mTask.reCreate();
                }
            }
        }
    }

    static class UpDateTask implements Runnable {

        private long rxBytes;
        private long preRxBytes;
        private long mDownloadSpeed;
        private double mInterval = 1000;

        private PendingIntent mResultPendingIntent;
        private final Context mContext;
        private boolean isRun = true;
        int i = 0;
        private final NotificationManager mNotificationManager;
        private boolean isClean;

        public UpDateTask(Context context) {
            mContext = context;
            mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            createNotify();
            initBroadCastReceiver();
            rxBytes = TrafficStats.getTotalRxBytes();
            preRxBytes = rxBytes;
        }

        /**
         * 初始化本地广播接收者
         */
        private void initBroadCastReceiver() {
            LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(mContext);
            IntentFilter filter = new IntentFilter("TileChangeListener");
            broadcastManager.registerReceiver(new TileChangeListenerReceiver(this), filter);
        }

        @Override
        public void run() {
            while (isRun) {
                upDateNotify();
                i++;
                SystemClock.sleep((long) mInterval);
            }
        }

        public void reCreate() {
            isClean = false;
            upDateNotify();
        }

        public void clean() {
            isClean = true;
            mNotificationManager.cancel(Config.NOTIFY_ID);
        }

        public void stop() {
            isRun = false;
            mNotificationManager.cancel(Config.NOTIFY_ID);
        }

        private void createNotify() {
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(mContext)
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher_round))
                            .setContentTitle("My notification")
                            .setContentText("Hello World!");

            Intent resultIntent = new Intent(mContext, SettingActivity.class);

            TaskStackBuilder stackBuilder = TaskStackBuilder.create(mContext);
            stackBuilder.addParentStack(SettingActivity.class);
            stackBuilder.addNextIntent(resultIntent);
            mResultPendingIntent = stackBuilder.getPendingIntent(
                    0, PendingIntent.FLAG_UPDATE_CURRENT);
            mBuilder.setContentIntent(mResultPendingIntent);
            Notification notification = mBuilder.build();
            notification.flags |= Notification.FLAG_NO_CLEAR;
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            mNotificationManager.notify(Config.NOTIFY_ID, notification);
        }

        private void upDateNotify() {
            if (isClean) {
                return;
            }
            rxBytes = TrafficStats.getTotalRxBytes();
            mDownloadSpeed = (long) ((rxBytes - preRxBytes) * 1d / mInterval * 1000 + .5d);
            preRxBytes = rxBytes;
            Log.i(TAG, "handleMessage: " + mDownloadSpeed);

            String[] split = NetUtil.formatNetSpeed(mDownloadSpeed);
            String downSpeed;
            downSpeed = "" + Formatter.formatFileSize(mContext, mDownloadSpeed);

            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(mContext)
                            .setSmallIcon(R.mipmap.ic_launcher_round)
                            .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher))
                            .setContentTitle("下行网速")
                            .setContentText(downSpeed);

            mBuilder.setContentIntent(mResultPendingIntent);
            Notification notification = mBuilder.build();
            notification.flags |= Notification.FLAG_NO_CLEAR;

            Class<? extends Notification> notificationClass = notification.getClass();
            try {
                Method setSmallIcon = notificationClass.getDeclaredMethod("setSmallIcon", Class.forName("android.graphics.drawable.Icon"));
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    Icon icon = Icon.createWithBitmap(NetTextIconFactory.createSingleIcon(split[0], split[1]));
                    setSmallIcon.invoke(notification, icon);
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            mNotificationManager.notify(Config.NOTIFY_ID, notification);
        }

    }
}
